package org.springblade.tms.module.supercargoinfo.base;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.ApiOperation;
import org.apache.logging.log4j.util.Strings;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.tms.global.entity.TimeInterval;
import org.springblade.tms.global.enums.ApprovalStatusEnum;
import org.springblade.tms.global.enums.SapActionEnum;
import org.springblade.tms.global.enums.TableNameEnum;
import org.springblade.tms.global.enums.UserTypeEnum;
import org.springblade.tms.global.exception.CommonException;
import org.springblade.tms.module.approval.entity.TMApproval;
import org.springblade.tms.module.approval.service.IApprovalService;
import org.springblade.tms.module.carriercarrelation.entity.TMCarrierCarRelation;
import org.springblade.tms.module.carriersupercargorelation.entity.TMCarrierSupercargoRelation;
import org.springblade.tms.module.carriersupercargorelation.service.ICarrierSupercargoRelationService;
import org.springblade.tms.module.sap.base.SapRequestService;
import org.springblade.tms.module.supercargoinfo.entity.TMSupercargoInfo;
import org.springblade.tms.module.supercargoinfo.service.ISupercargoInfoService;
import org.springblade.tms.module.supercargoinfo.vo.EscortVo;
import org.springblade.tms.module.supercargoinfo.vo.TMSupercargoInfoVO;
import org.springblade.tms.module.userinfo.dto.CarrierAuditReq;
import org.springblade.tms.module.userinfo.entity.TMUserInfo;
import org.springblade.tms.module.userinfo.service.IUserInfoService;
import org.springblade.tms.module.userinfo.vo.QualificationReviewCarrier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @projectName: BladeX
 * @package: org.springblade.tms.module.supercargoinfo.base
 * @className: EscortManagementService
 * @author: yr
 * @description: 押运员服务类
 * @date: 2022/3/10 15:44
 */
@Service
@Transactional
public class EscortManagementService {
	@Resource
	private ISupercargoInfoService supercargoInfoService;
	@Resource
	private ICarrierSupercargoRelationService carrierSupercargoRelationService;
	@Resource
	private IUserInfoService userInfoService;
	@Resource
	private IApprovalService approvalService;
	@Resource
	private SapRequestService sapRequestService;

	/**
	 * @param tmSupercargoInfo:
	 * @return R
	 * @author yr
	 * @description 新增或修改押运员
	 * @date 2022/3/23 11:59
	 */
	public R saveOrUpdate(TMSupercargoInfo tmSupercargoInfo, TMUserInfo one) {
		//tmSupercargoInfo为空时为新增，不为空时为修改
		tmSupercargoInfo.setApprovalStatus(ApprovalStatusEnum.PENDING_REVIEW.getValue());
		if (tmSupercargoInfo.getId() == null) {
			TMSupercargoInfo supercargoInfo = supercargoInfoService.lambdaQuery().eq(TMSupercargoInfo::getPhone, tmSupercargoInfo.getPhone()).one();
			if (supercargoInfo != null) {
				if (one != null && one.getUserType().equals(UserTypeEnum.CARRIER.getValue())) {
					if (carrierSupercargoRelationService.lambdaQuery().eq(TMCarrierSupercargoRelation::getRelationSupercargoNo, supercargoInfo.getId())
						.eq(TMCarrierSupercargoRelation::getRelationCarrierNo, one.getId()).one() != null) {
						CommonException.throwCommonException("押运员已存在");
					}
					R<Object> r = new R<>();
					r.setCode(206);
					r.setSuccess(true);
					r.setMsg("系统中已存在该押运员，是否进行绑定？");
					return r;
				} else {
					CommonException.throwCommonException("手机号已存在");
				}
			}
			//判断押运员身份证号是否存在
			TMSupercargoInfo supercargoInfo1 = supercargoInfoService.lambdaQuery().eq(TMSupercargoInfo::getIdCardNo, tmSupercargoInfo.getIdCardNo()).one();
			if (supercargoInfo1 != null) {
				throw CommonException.throwCommonException("押运员身份证号已存在");
			}
			boolean save = supercargoInfoService.save(tmSupercargoInfo);
			//新增审批单
			TMSupercargoInfo info = supercargoInfoService.lambdaQuery().select(TMSupercargoInfo::getId).eq(TMSupercargoInfo::getPhone, tmSupercargoInfo.getPhone()).one();
			TMApproval approval = new TMApproval();
			approval.setApprovalStatus(ApprovalStatusEnum.PENDING_REVIEW.getValue());
			approval.setRelationId(info.getId());
			approval.setRelationTableName(TableNameEnum.TM_SUPERCARGO_INFO.value());
			approvalService.save(approval);
			//获取当前用户判断是否为承运商，是承运商将该司机绑定给当前用户
			if (one != null && one.getUserType().equals(UserTypeEnum.CARRIER.getValue())) {
				TMCarrierSupercargoRelation tmCarrierSupercargoRelation = new TMCarrierSupercargoRelation();
				tmCarrierSupercargoRelation.setRelationCarrierNo(one.getId());
				tmCarrierSupercargoRelation.setRelationSupercargoNo(info.getId());
				carrierSupercargoRelationService.save(tmCarrierSupercargoRelation);
			}
			return R.status(save);
		} else {
			//判断押运员身份证号是否存在
			TMSupercargoInfo supercargoInfo1 = supercargoInfoService.lambdaQuery().eq(TMSupercargoInfo::getIdCardNo, tmSupercargoInfo.getIdCardNo())
				.ne(TMSupercargoInfo::getId, tmSupercargoInfo.getId()).one();
			if (supercargoInfo1 != null) {
				throw CommonException.throwCommonException("押运员身份证号已存在");
			}
			TMSupercargoInfo supercargoInfo = supercargoInfoService.lambdaQuery().eq(TMSupercargoInfo::getPhone, tmSupercargoInfo.getPhone())
				.ne(TMSupercargoInfo::getId, tmSupercargoInfo.getId()).one();
			if (supercargoInfo != null) {
				return R.success("手机号已存在");
			}
			boolean update = supercargoInfoService.updateById(tmSupercargoInfo);
			//修改审批单状态为审批中
			TMApproval approval = approvalService.lambdaQuery().eq(TMApproval::getRelationId, tmSupercargoInfo.getId()).one();
			approval.setApprovalStatus(ApprovalStatusEnum.PENDING_REVIEW.getValue());
			approval.setRemarkReject("");
			approvalService.updateById(approval);
			return R.status(update);
		}
	}

	/**
	 * @param carrierAuditReq:
	 * @return R
	 * @author yr
	 * @description 押运员审核
	 * @date 2022/3/10 18:22
	 */
	public R check(List<CarrierAuditReq> carrierAuditReq) {
		if (carrierAuditReq.size() == 1) {
			CarrierAuditReq auditReq = carrierAuditReq.get(0);
			TMApproval one = approvalService.lambdaQuery().eq(TMApproval::getRelationId, auditReq.getId()).one();
			TMSupercargoInfo info = supercargoInfoService.lambdaQuery().eq(TMSupercargoInfo::getId, auditReq.getId()).one();
			if (auditReq.getPass()) {
				one.setApprovalStatus(ApprovalStatusEnum.PASSED.getValue());
				one.setRemarkReject("");
				approvalService.updateById(one);
				info.setApprovalStatus(ApprovalStatusEnum.PASSED.getValue());
				boolean update = supercargoInfoService.updateById(info);
				ArrayList<TMSupercargoInfo> supercargoInfoList = new ArrayList<>();
				supercargoInfoList.add(info);

				R driverMasterData = sapRequestService.escortMasterData(supercargoInfoList, SapActionEnum.S.getValue());
				if (driverMasterData.getMsg().equals("操作失败")) {
					throw CommonException.throwCommonException("上报TM失败");
				}
				return R.status(update);
			} else {
				one.setApprovalStatus(ApprovalStatusEnum.REJECTED.getValue());
				one.setRemarkReject(auditReq.getReasonForRejection());
				boolean updateById = approvalService.updateById(one);
				info.setApprovalStatus(ApprovalStatusEnum.REJECTED.getValue());
				boolean update = supercargoInfoService.updateById(info);
				return R.status(update && updateById);
			}
		} else {
			List<Long> ids = carrierAuditReq.stream().map(CarrierAuditReq::getId).collect(Collectors.toList());
			List<TMSupercargoInfo> tmSupercargoInfoList = supercargoInfoService.lambdaQuery().in(TMSupercargoInfo::getId, ids).list();
			tmSupercargoInfoList.forEach(supercargoInfo -> supercargoInfo.setApprovalStatus(ApprovalStatusEnum.PASSED.getValue()));
			boolean updateBatchById = supercargoInfoService.updateBatchById(tmSupercargoInfoList);
			List<TMApproval> tmApprovalList = approvalService.lambdaQuery().in(TMApproval::getRelationId, ids).list();
			tmApprovalList.forEach(approval -> approval.setApprovalStatus(ApprovalStatusEnum.PASSED.getValue()));
			boolean batchById = approvalService.updateBatchById(tmApprovalList);
			R driverMasterData = sapRequestService.escortMasterData(tmSupercargoInfoList, SapActionEnum.S.getValue());
			if (driverMasterData.getMsg().equals("操作失败")) {
				throw CommonException.throwCommonException("上报TM失败");
			}
			return R.status(batchById && updateBatchById);
		}
	}

	/**
	 * @param :
	 * @return TMUserInfo
	 * @author yr
	 * @description 获取当前用户
	 * @date 2022/3/8 15:17
	 */
	private TMUserInfo getTmUserInfo() {
		Long userId = AuthUtil.getUser().getUserId();
		return userInfoService.lambdaQuery().eq(TMUserInfo::getParentId, userId).one();
	}

	/**
	 * @param tmSupercargoInfo:
	 * @param query:
	 * @param timeInterval:
	 * @return R<IPage>
	 * @author yr
	 * @description 押运员列表查询
	 * @date 2022/3/11 9:54
	 */
	public R<IPage> list(TMSupercargoInfoVO tmSupercargoInfo, Query query, TimeInterval timeInterval) {
		LocalDateTime expireDate = LocalDateTime.now().plusMonths(1);
		List<Long> driverIds = new ArrayList<>();
		if (Strings.isNotBlank(tmSupercargoInfo.getCarrierId())) {
			List<TMCarrierSupercargoRelation> carrierSupercargoRelations = carrierSupercargoRelationService.lambdaQuery()
				.select(TMCarrierSupercargoRelation::getRelationSupercargoNo)
				.eq(TMCarrierSupercargoRelation::getRelationCarrierNo, tmSupercargoInfo.getCarrierId())
				.list();
			driverIds = carrierSupercargoRelations.stream().map(TMCarrierSupercargoRelation::getRelationSupercargoNo).collect(Collectors.toList());
		}
		TMUserInfo one = getTmUserInfo();
		IPage<TMSupercargoInfo> pages = supercargoInfoService.page(Condition.getPage(query), Condition.getQueryWrapper(new TMSupercargoInfo()).lambda()
			.like(tmSupercargoInfo.getName() != null && !tmSupercargoInfo.getName().isEmpty(), TMSupercargoInfo::getName, tmSupercargoInfo.getName())
			.like(tmSupercargoInfo.getPhone() != null && !tmSupercargoInfo.getPhone().isEmpty(), TMSupercargoInfo::getPhone, tmSupercargoInfo.getPhone())
			.eq(tmSupercargoInfo.getApprovalStatus() != null && !tmSupercargoInfo.getApprovalStatus().isEmpty(), TMSupercargoInfo::getApprovalStatus, tmSupercargoInfo.getApprovalStatus())
			.ge(timeInterval.getStart() != null, TMSupercargoInfo::getCreateTime, timeInterval.getStart())
			.le(timeInterval.getEnd() != null, TMSupercargoInfo::getCreateTime, timeInterval.getEnd())
			.and(tmSupercargoInfo.getExpireDate(), supercargoInfoLambdaQueryWrapper -> supercargoInfoLambdaQueryWrapper
				.le(TMSupercargoInfo::getValidityPeriod, expireDate).or()
				.le(TMSupercargoInfo::getIdCardValidEnd, expireDate))
			.notIn(!driverIds.isEmpty(), TMSupercargoInfo::getId, driverIds)
			.orderByDesc(TMSupercargoInfo::getUpdateTime, TMSupercargoInfo::getId));
		//判断当前用户是否为承运商
		if (one != null && one.getUserType().equals(UserTypeEnum.CARRIER.getValue())) {
			List<TMCarrierSupercargoRelation> list = carrierSupercargoRelationService.lambdaQuery()
				.select(TMCarrierSupercargoRelation::getRelationSupercargoNo)
				.eq(TMCarrierSupercargoRelation::getRelationCarrierNo, one.getId())
				.list();
			List<Long> driverId = list.stream().map(TMCarrierSupercargoRelation::getRelationSupercargoNo).collect(Collectors.toList());
			pages = supercargoInfoService.page(Condition.getPage(query), Condition.getQueryWrapper(new TMSupercargoInfo())
				.lambda().in(!driverId.isEmpty(), TMSupercargoInfo::getId, driverId).apply(driverId.isEmpty(), "1=2")
				.like(tmSupercargoInfo.getName() != null && !tmSupercargoInfo.getName().isEmpty(), TMSupercargoInfo::getName, tmSupercargoInfo.getName())
				.like(tmSupercargoInfo.getPhone() != null && !tmSupercargoInfo.getPhone().isEmpty(), TMSupercargoInfo::getPhone, tmSupercargoInfo.getPhone())
				.eq(tmSupercargoInfo.getApprovalStatus() != null && !tmSupercargoInfo.getApprovalStatus().isEmpty(), TMSupercargoInfo::getApprovalStatus, tmSupercargoInfo.getApprovalStatus())
				.ge(timeInterval.getStart() != null, TMSupercargoInfo::getCreateTime, timeInterval.getStart())
				.le(timeInterval.getEnd() != null, TMSupercargoInfo::getCreateTime, timeInterval.getEnd())
				.notIn(!driverIds.isEmpty(), TMSupercargoInfo::getId, driverIds)
				.orderByDesc(TMSupercargoInfo::getUpdateTime, TMSupercargoInfo::getId));
		}
		pages.getRecords().forEach(supercargoInfo -> supercargoInfo.setApprovalStatus(ApprovalStatusEnum.getDescriptionByValue(supercargoInfo.getApprovalStatus())));
		//获取审核表的驳回原因
		List<Long> ids = pages.getRecords().stream().map(TMSupercargoInfo::getId).collect(Collectors.toList());
		List<TMApproval> tmApprovalList = approvalService.lambdaQuery().in(!ids.isEmpty(), TMApproval::getRelationId, ids)
			.apply(ids.isEmpty(), "1=2").list();
		Map<Long, String> remarkReject = tmApprovalList.stream().collect(Collectors.toMap(TMApproval::getRelationId, TMApproval::getRemarkReject));
		LinkedList<EscortVo> list = new LinkedList<>();
		for (TMSupercargoInfo record : pages.getRecords()) {
			EscortVo escortVo = BeanUtil.copy(record, EscortVo.class);
			escortVo.setRemarkReject(remarkReject.get(record.getId()));
			list.add(escortVo);
		}
		IPage page = pages;
		page.setRecords(list);
		return R.data(page);
	}

	/**
	 * @param ids:
	 * @return R
	 * @author yr
	 * @description 删除押运员
	 * @date 2022/3/11 10:48
	 */
	public R delete(List<Long> ids) {
		//判断当前用户是否为承运商
		TMUserInfo tmUserInfo = getTmUserInfo();
		if (tmUserInfo != null && tmUserInfo.getUserType().equals(UserTypeEnum.CARRIER.getValue())) {
			carrierSupercargoRelationService.remove(Condition.getQueryWrapper(new TMCarrierSupercargoRelation())
				.lambda().eq(TMCarrierSupercargoRelation::getRelationCarrierNo, tmUserInfo.getId())
				.in(TMCarrierSupercargoRelation::getRelationSupercargoNo, ids));
			List<TMCarrierSupercargoRelation> list = carrierSupercargoRelationService.lambdaQuery().in(TMCarrierSupercargoRelation::getRelationSupercargoNo, ids)
				.select(TMCarrierSupercargoRelation::getRelationSupercargoNo).list();
			List<Long> driverIds = list.stream().map(TMCarrierSupercargoRelation::getRelationSupercargoNo).collect(Collectors.toList());
			ids.removeAll(driverIds);
			List<TMSupercargoInfo> supercargoInfoList = supercargoInfoService.lambdaQuery().in(!ids.isEmpty(), TMSupercargoInfo::getId, ids)
				.apply(ids.isEmpty(), "1=2").list();
			if (ids.isEmpty()) {
				return R.status(true);
			}
			boolean deleteLogic = supercargoInfoService.deleteLogic(ids);
			reportTm(supercargoInfoList);
			return R.status(deleteLogic);
		} else {
			List<TMSupercargoInfo> supercargoInfoList = supercargoInfoService.lambdaQuery().in(!ids.isEmpty(), TMSupercargoInfo::getId, ids)
				.apply(ids.isEmpty(), "1=2").list();
			boolean deleteLogic = supercargoInfoService.deleteLogic(ids);
			reportTm(supercargoInfoList);
			return R.status(deleteLogic);
		}
	}

	//将删除状态上报到tm
	private void reportTm(List<TMSupercargoInfo> supercargoInfoList) {
		R driverMasterData = sapRequestService.escortMasterData(supercargoInfoList, SapActionEnum.D.getValue());
		if (driverMasterData.getMsg().equals("操作失败")) {
			throw CommonException.throwCommonException("上报TM失败");
		}
	}


	//导入excel时新增
	public R save(TMSupercargoInfo tmSupercargoInfo, TMUserInfo one) {
		tmSupercargoInfo.setApprovalStatus(ApprovalStatusEnum.PENDING_REVIEW.getValue());
		TMSupercargoInfo supercargoInfo = supercargoInfoService.lambdaQuery().eq(TMSupercargoInfo::getPhone, tmSupercargoInfo.getPhone()).one();
		if (supercargoInfo != null) {
			if (one != null && one.getUserType().equals(UserTypeEnum.CARRIER.getValue())) {
				if (carrierSupercargoRelationService.lambdaQuery().eq(TMCarrierSupercargoRelation::getRelationSupercargoNo, supercargoInfo.getId())
					.eq(TMCarrierSupercargoRelation::getRelationCarrierNo, one.getId()).one() != null) {
					CommonException.throwCommonException("押运员已存在");
				}
				R<Object> r = new R<>();
				r.setCode(206);
				r.setSuccess(true);
				r.setMsg("系统中已存在该押运员，是否进行绑定？");
				return r;
			} else {
				CommonException.throwCommonException("手机号已存在");
			}
		}
		//判断押运员身份证号是否存在
		TMSupercargoInfo supercargoInfo1 = supercargoInfoService.lambdaQuery().eq(TMSupercargoInfo::getIdCardNo, tmSupercargoInfo.getIdCardNo()).one();
		if (supercargoInfo1 != null) {
			throw CommonException.throwCommonException("押运员身份证号已存在");
		}
		boolean save = supercargoInfoService.save(tmSupercargoInfo);
		//新增审批单
		TMSupercargoInfo info = supercargoInfoService.lambdaQuery().select(TMSupercargoInfo::getId).eq(TMSupercargoInfo::getPhone, tmSupercargoInfo.getPhone()).one();
		TMApproval approval = new TMApproval();
		approval.setApprovalStatus(ApprovalStatusEnum.PENDING_REVIEW.getValue());
		approval.setRelationId(info.getId());
		approval.setRelationTableName(TableNameEnum.TM_SUPERCARGO_INFO.value());
		approval.setTenantId(tmSupercargoInfo.getTenantId());
		approvalService.save(approval);
		//获取当前用户判断是否为承运商，是承运商将该司机绑定给当前用户
		if (one != null && one.getUserType().equals(UserTypeEnum.CARRIER.getValue())) {
			TMCarrierSupercargoRelation tmCarrierSupercargoRelation = new TMCarrierSupercargoRelation();
			tmCarrierSupercargoRelation.setRelationCarrierNo(one.getId());
			tmCarrierSupercargoRelation.setRelationSupercargoNo(info.getId());
			tmCarrierSupercargoRelation.setTenantId(tmSupercargoInfo.getTenantId());
			carrierSupercargoRelationService.save(tmCarrierSupercargoRelation);
		}
		return R.status(save);
	}


}
